#pragma once

struct QueueItem
{
	enum TYPE {
		MARKET,
		ORDER,
		CANCELLATION,
		QUERY_MBL,
		TIMEOUT,
		ORDER_NOTIFICATION,
		COMMAND,
		CONTRACT,
		EXCHANGE_NOTIFY,
		PENDING_MARKET,
		PENDING_CONTRACT,
		TIMER_COMMAND,
		WAITABLE_TIMER
	};
	UINT type;
	UINT size;
	char data[2048];
};

class FastBlockQueue : public boost::noncopyable
{
	static const int DATA_CAPACITY = 1024;
private:
	explicit FastBlockQueue(HANDLE hQuit);
public:
	typedef std::tr1::shared_ptr<FastBlockQueue> FastBlockQueuePtr; 

	~FastBlockQueue();

	static FastBlockQueue* Create(HANDLE hQuit);

	HANDLE GetEvent() const { return m_hEvent;} 

	UINT Size() const
	{
		m_cs.Lock();
		UINT size = m_end - m_current;
		m_cs.Unlock();
		return size;
	}

	void Clear()
	{
		m_cs.Lock();
		m_end = m_current = 0;
		m_cs.Unlock();
	}

	void Push(QueueItem const& data);

	QueueItem& Pop(bool& quitFlag);

	bool AlertablePop(bool& quitFlag,QueueItem& item);

private:
	bool IsEmpty() const
	{
		return m_current >= m_end;
	}

	QueueItem m_datas[DATA_CAPACITY];
	UINT m_current;
	UINT m_end;
	mutable CCriticalSection m_cs;
	HANDLE m_hEvent;
	HANDLE m_hQuit;
};

